﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;



namespace SilverlightMenu
{
    using ESRI.ArcGIS.Client;
    using System.Text;
    using ESRI.ArcGIS.Client.Geometry;


    /// <summary>
    /// 综合查询
    /// </summary>
    public partial class QueryTask : Page
    {
        QueryTaskModel model = null;

        public ChildWindow Window = null;

        /// <summary>
        /// 显示内容用的BOX
        /// </summary>
        public ListBox MainBox = null;

        /// <summary>
        /// 分页控件
        /// </summary>
        public DataPager pager = null;

        public QueryTask()
        {
            InitializeComponent();


            MainBox = grid;
            pager = gataPager;
            Grid gridx = new Grid();


            Window = new ChildWindow() { Content = gridx, OverlayOpacity = 0 };
            Window.DataContext = DataContext = model = new QueryTaskModel(this);

            model.列出服务中所有的图层();


            LayoutRoot.Children.Remove(grid);
            LayoutRoot.Children.Remove(gataPager);
            grid.Visibility = Visibility.Visible;
            gridx.Children.Add(grid);
            gridx.Children.Add(gataPager);



            pager.PageIndexChanged += (s, e) =>
            {
                model.PageerChanged(s, e);
            };

        }


        /// <summary>
        /// 选择图层发生改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = ((ComboBox)sender);
            //如果选择的是有效的图层
            if (comboBox.SelectedItem != null && comboBox.SelectedItem is LayerInfo)
            {
                model.SelectLayerInofByID((comboBox.SelectedItem as LayerInfo).ID);

                ((GraphicsLayer)MapControl.Layers["gLayer"]).Graphics.Clear();

                //显示明细窗口
                Window.Show();
            }
        }
        /// <summary>
        /// 选择数据发生改变是导航到选择的地方
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void grid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (MainBox.SelectedItem is FrameworkElement)
            {
                if ((MainBox.SelectedItem as FrameworkElement).Tag != null)
                {
                    model.GrapatchSelectByComboxItem((MainBox.SelectedItem as FrameworkElement).Tag as Graphic);
                }
            }
        }

        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentField.Text == null || CurrentField.Text == "")
            {
                model.QueryByDisplayNameValue(txt线路名称.Text);
            }
            else
            {
                long longt=0;
                decimal decimalt = 0;
                string value = long.TryParse(txt线路名称.Text,out longt) ? txt线路名称.Text : "'" + txt线路名称.Text + "'";
                value = decimal.TryParse(txt线路名称.Text, out decimalt) ? txt线路名称.Text : "'" + txt线路名称.Text + "'";

                model.QueryDraw(CurrentField.Text + "=" + value + "");
            }
        }

        /// <summary>
        /// 选择查询的字段名发生改变时
        /// 需要动态改变 值集合
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FieldNamesEnmu_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            model.FieldNamesEnmu_SelectionChanged(sender, e);
        }


    }


    /// <summary>
    /// 综合查询的逻辑
    /// </summary>
    public class QueryTaskModel : System.ComponentModel.INotifyPropertyChanged
    {

        #region 构造函数
        /// <summary>
        /// 创建一个新的  QueryTaskModel
        /// </summary>
        public QueryTaskModel(QueryTask queryTask)
        {
            _queryTask = queryTask;
        }
        #endregion

        #region 变量定义
        /// <summary>
        /// 要查询的地图默认URL
        /// </summary>
        public const string MapServerUrl = "http://192.168.58.91:4500/ArcGIS/rest/services/BT/MapServer";
        /// <summary>
        /// UI对像
        /// </summary>
        QueryTask _queryTask = null;

        /// <summary>
        /// 查询用的图层对像 这个对像主要用于提供图层信息
        /// </summary>
        private ArcGISDynamicMapServiceLayer queryTaskLayer = null;


        /// <summary>
        /// 当前的工作URL
        /// </summary>
        protected string WorkUrl = MapServerUrl;

        /// <summary>
        /// 定义一个有返回值的委托
        /// </summary>
        /// <returns></returns>
        delegate int RetAction();

        #endregion


        #region 公共属性

        /// <summary>
        /// UI对像
        /// </summary>
        public QueryTask QueryTaskUI
        {
            get { return _queryTask; }
        }

        /// <summary>
        /// 查询用的图层对像 这个对像主要用于提供图层信息
        /// </summary>
        public ArcGISDynamicMapServiceLayer QueryTaskLayer
        {
            get { return queryTaskLayer; }
        }

        private IEnumerable<LayerInfo> _LayerInofs = null;
        /// <summary>
        /// 图层信息集合
        /// </summary>
        public IEnumerable<LayerInfo> LayerInofs
        {
            get { return _LayerInofs; }
            set
            {
                _LayerInofs = value;
                OnPropertyChanged("LayerInofs");
            }
        }



        private object _Detalis = new ESRI.ArcGIS.Client.Tasks.FeatureSet();
        /// <summary>
        /// 选中图层的记录
        /// </summary>
        public object Detalis
        {
            get
            {
                if (_Detalis is ESRI.ArcGIS.Client.Tasks.FeatureSet)
                {


                    return new System.Windows.Data.PagedCollectionView((_Detalis as ESRI.ArcGIS.Client.Tasks.FeatureSet).Features);
                }

                return _Detalis;
            }
            set
            {
                _Detalis = value;

                OnPropertyChanged("Detalis");
            }
        }
        
        /// <summary>
        /// 当前选择查询图层的 事件数据
        /// </summary>
        private ESRI.ArcGIS.Client.Tasks.QueryEventArgs QueryEventArgs = null;

        private string _WhereName = "";
        /// <summary>
        /// 用于搜索的主要字段名
        /// </summary>
        public string WhereName
        {
            get { return _WhereName; }
            set
            {

                _WhereName = value;
                OnPropertyChanged("WhereName");
            }
        }

        private System.Collections.ObjectModel.ObservableCollection<string> _FieldContentEnmu = new System.Collections.ObjectModel.ObservableCollection<string>();
        /// <summary>
        /// 字段枚举
        /// </summary>
        public System.Collections.Generic.IEnumerable<string> FieldContentEnmu
        {
            get { return _FieldContentEnmu; }
            set
            {
                if (value != null)
                {
                    _FieldContentEnmu.Clear();
                    foreach (var item in value)
                    {
                        _FieldContentEnmu.Add(item);
                    }
                }
                OnPropertyChanged("FieldContentEnmu");
            }
        }

        /// <summary>
        /// 字段名列表
        /// </summary>
        private System.Collections.ObjectModel.ObservableCollection<string> _FieldNames = new System.Collections.ObjectModel.ObservableCollection<string>();

        /// <summary>
        /// 字段名列表
        /// </summary>
        public System.Collections.Generic.IEnumerable<string> FieldNames
        {
            get { return _FieldNames; }
            set
            {

                if (value != null)
                {
                    _FieldNames.Clear();
                    foreach (var item in value)
                    {
                        _FieldNames.Add(item);
                    }
                }
                OnPropertyChanged("FieldNames");
            }
        }


        #endregion

        #region 公共方法


        /// <summary>
        /// 选择查询的字段名发生改变时
        /// 需要动态改变 值集合
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void FieldNamesEnmu_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //如果有选中值
            if (((System.Windows.Controls.Primitives.Selector)sender).SelectedItem != null)
            {
                WhereName = ((System.Windows.Controls.Primitives.Selector)sender).SelectedItem.ToString();
                UpdateFieldContentEnmu(QueryEventArgs);

            }
        }

        /// <summary>
        /// 指定ID  选中图层 得到选中图层的 数据信息
        /// </summary>
        /// <param name="LayerID"></param>
        public void SelectLayerInofByID(int LayerID)
        {
            //创建一个查询做业对像
            ESRI.ArcGIS.Client.Tasks.QueryTask queryTaskTemp = new ESRI.ArcGIS.Client.Tasks.QueryTask(MapServerUrl + "/" + LayerID);

            //改变当前工作的URL
            WorkUrl = MapServerUrl + "/" + LayerID;

            //创建一个查询
            ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
            //指定查询加载的事件
            //查询完成
            queryTaskTemp.ExecuteCompleted += (s, e) =>
            {
                //更新事件数据
                QueryEventArgs = e;

                #region 查询完成事件
                Detalis = e.FeatureSet;
                WhereName = e.FeatureSet.DisplayFieldName;

                UpdateFieldContentEnmu(e);


                FieldNames = e.FeatureSet.FieldAliases.Select(p => p.Key);
                #endregion
            };
            //查询失败
            queryTaskTemp.Failed += (s, e) =>
            {
                MessageBox.Show(e.Error.ToString());
            };

            // 指定返回的字段名称 * 表示所有
            query.OutFields.Add("*");
            query.Where = " 1=1 ";
            //执行查询
            queryTaskTemp.ExecuteAsync(query);
        }

        /// <summary>
        /// 列出 这个图层中所有的 URL
        /// </summary>
        public void 列出服务中所有的图层()
        {
            ///创建一个临时层变量
            ArcGISDynamicMapServiceLayer layer = LoadMapServerByUrl(MapServerUrl);

            ///将图层添加到地图控件中
            ///不添加将不会加载图层
            QueryTaskUI.MapControl.Layers.Insert(0, layer);
        }

        /// <summary>
        /// 分页控件页面发生改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PageerChanged(object sender, EventArgs e)
        {

            if (QueryTaskUI.pager.Source == null)
            {
                return;
            }

            //得到当前数据的 FeatureSet
            ESRI.ArcGIS.Client.Tasks.FeatureSet FeatureSet = ((ESRI.ArcGIS.Client.Tasks.FeatureSet)_Detalis);

            #region 动态生成模板
            int Index = 0;
            IEnumerable<string> TextBlocks = from p in FeatureSet.FieldAliases
                                             let index = Index++
                                             select
             "                        <TextBlock Text=\"##" + p.Key + "##\" Grid.Column=\"" + index + "\"/> \r\n"
                ;

            IEnumerable<string> ColumnDefinitions = from p in FeatureSet.FieldAliases
                                                    let Count = FeatureSet.FieldAliases.Count
                                                    select
                        "                        <ColumnDefinition Width=\"" + (3800.0 / Count).ToString("f2") + "\" />  \r\n"
                ;
            StringBuilder DataTemplateStr = new StringBuilder();
            DataTemplateStr.AppendLine("                    <Grid xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"> ");
            DataTemplateStr.AppendLine("                        <Grid.ColumnDefinitions> ");
            DataTemplateStr.AppendLine(string.Join("", ColumnDefinitions.ToArray()));
            DataTemplateStr.AppendLine("                        </Grid.ColumnDefinitions> ");
            DataTemplateStr.AppendLine(string.Join("", TextBlocks.ToArray()));
            DataTemplateStr.AppendLine("                    </Grid> ");


            #endregion

            ((ListBox)QueryTaskUI.MainBox).Items.Clear();
            //索引
            Index = 0;



            foreach (Graphic o in QueryTaskUI.pager.Source)
            {
                //这一行的值
                string ValueStr = DataTemplateStr.ToString();
                if (Index == 0)
                {
                    #region 添加到第一行做为表格的头
                    //处理各属性
                    foreach (var perInfo in FeatureSet.FieldAliases)
                    {
                        ValueStr = ValueStr.Replace("##" + perInfo.Key + "##", perInfo.Key.ToString());
                    }
                    //添加到数据中
                    ((ListBox)QueryTaskUI.MainBox).Items.Add((FrameworkElement)System.Windows.Markup.XamlReader.Load(ValueStr));

                    #endregion

                    ValueStr = DataTemplateStr.ToString();
                    //处理各属性
                    foreach (var perInfo in FeatureSet.FieldAliases)
                    {
                        ValueStr = ValueStr.Replace("##" + perInfo.Key + "##", o.Attributes[perInfo.Key].ToString());
                    }

                }

                else
                {

                    //处理各属性
                    foreach (var perInfo in FeatureSet.FieldAliases)
                    {
                        ValueStr = ValueStr.Replace("##" + perInfo.Key + "##", o.Attributes[perInfo.Key].ToString());
                    }


                }
                FrameworkElement el = (FrameworkElement)System.Windows.Markup.XamlReader.Load(ValueStr);
                el.Tag = o;
                //添加到数据中
                ((ListBox)QueryTaskUI.MainBox).Items.Add(el);
                Index++;

            }

        }


        /// <summary>
        /// 从ComBoxItem中得到 graphic 选中地图
        /// </summary>
        public void GrapatchSelectByComboxItem(Graphic graphic)
        {

            Graphic selectedFeature = graphic;

            if (graphic.Geometry is MapPoint)
            {
                //高亮选择要素
                selectedFeature.Symbol = new ESRI.ArcGIS.Client.Symbols.SimpleMarkerSymbol() { Color = new SolidColorBrush(Colors.Blue) };
            }

            if (graphic.Geometry is ESRI.ArcGIS.Client.Geometry.Polyline)
            {
                //高亮选择要素
                selectedFeature.Symbol = new ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol() { Color = new SolidColorBrush(Colors.Blue), Width = 3 };
            }
            if (graphic.Geometry is ESRI.ArcGIS.Client.Geometry.Polygon)
            {
                //高亮选择要素
                selectedFeature.Symbol = new ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol() { Fill = new SolidColorBrush(Color.FromArgb(100, 0, 0, 255)), BorderBrush = new SolidColorBrush(Colors.Blue), BorderThickness = 1 };
            }

            if (!((GraphicsLayer)QueryTaskUI.MapControl.Layers["gLayer"]).Graphics.Contains(selectedFeature))
            {
                //添加到图层中
                ((GraphicsLayer)QueryTaskUI.MapControl.Layers["gLayer"]).Graphics.Add(selectedFeature);
            }
            



            //得到范围
            Envelope selectedFeatureExtent = selectedFeature.Geometry.Extent;
            double expandPercentage = 30;
            double widthExpand = selectedFeatureExtent.Width * (expandPercentage / 100);
            double heightExpand = selectedFeatureExtent.Height * (expandPercentage / 100);
            Envelope displayExtent = new Envelope(
            selectedFeatureExtent.XMin - (widthExpand / 2),
            selectedFeatureExtent.YMin - (heightExpand / 2),
            selectedFeatureExtent.XMax + (widthExpand / 2),
            selectedFeatureExtent.YMax + (heightExpand / 2));


            //放大变小 注意这里加上  QueryTaskUI.MapControl.ZoomTo((Geometry)displayExtent);  后会出现 CPU占用100% 的情况.
            //目前还不清楚问题
            //QueryTaskUI.MapControl.ZoomTo((Geometry)displayExtent);
            QueryTaskUI.MapControl.PanTo(displayExtent);
        }

        /// <summary>
        /// 按 默认显示字段名中查询 结果将显示在 图层上
        /// </summary>
        /// <param name="StringValue">输入值</param>
        public void QueryByDisplayNameValue(string StringValue)
        {
            QueryDrawGraphicsLayer(WhereName + "='" + StringValue + "'", StringValue);
        }
        /// <summary>
        /// 按 输入条件  结果将显示在 图层上
        /// </summary>
        /// <param name="StringValue">输入条件</param>
        public void QueryDraw(string WhereStr)
        {
            QueryDrawGraphicsLayer(WhereStr);
        }

        #endregion


        #region 子类可见的方法

        /// <summary>
        /// 从URL加载MapServer 
        /// </summary>
        /// <param name="Url"></param>
        protected virtual ArcGISDynamicMapServiceLayer LoadMapServerByUrl(string Url)
        {

            //改变当前工作的URL
            WorkUrl = Url;
            ArcGISDynamicMapServiceLayer layer = new ArcGISDynamicMapServiceLayer() { Url = Url };
            queryTaskLayer = layer;

            //图层加载失败的事件
            layer.InitializationFailed += (s, e) =>
            {
                QueryTaskUI.MapControl.Layers.Remove(layer);
            };
            //加载图层完成
            layer.Initialized += (s, e) =>
            {
                QueryTaskUI.MapControl.Layers.Remove(layer);
                LayerInofs = layer.Layers.AsEnumerable();
            };
            layer.Opacity = 0;
            return layer;

        }

        /// <summary>
        /// 按输入的指定条件查询 将查询到的数据画到  GraphicsLayer 上
        /// </summary>
        /// <param name="WhereStr">查询用的条件字符串</param>
        protected virtual void QueryDrawGraphicsLayer(string WhereStr, string Summary = "")
        {



            ESRI.ArcGIS.Client.Tasks.QueryTask tempQueryTask = new ESRI.ArcGIS.Client.Tasks.QueryTask(WorkUrl);
            //查询完成
            tempQueryTask.ExecuteCompleted += (s, e) =>
            {
                //清空所有图层中的原素
                ((GraphicsLayer)QueryTaskUI.MapControl.Layers["gLayer"]).Graphics.Clear();
                ((ElementLayer)QueryTaskUI.MapControl.Layers["eLayer"]).Children.Clear();



                //添加选中原素
                for (int k = 0; k < e.FeatureSet.Features.Count; k++)
                {
                    //当前条件查询到的临时范围
                    Envelope envelope = null;

                    //将搜索到的图原进行范围 相交成新的更大的 范围
                    if (e.FeatureSet.Features[k].Geometry != null)
                    {
                        if (envelope == null)
                        {
                            //给区域传值
                            envelope = e.FeatureSet.Features[k].Geometry.Extent;

                            //添加说明
                            if (Summary != null && Summary != "")
                            {
                                TextBlock txt = new TextBlock() { Text = Summary };
                                txt.SetValue(ElementLayer.EnvelopeProperty, envelope.GetCenter().Extent);
                                ((ElementLayer)QueryTaskUI.MapControl.Layers["eLayer"]).Children.Add(txt);
                            }
                        }
                    }

                    //画图
                    GrapatchSelectByComboxItem(e.FeatureSet.Features[k]);
                }
            };
            //查询失败
            tempQueryTask.Failed += (s, e) =>
            {
                MessageBox.Show(e.Error.ToString());
            };

            //添加查询的字段 并执行查询
            tempQueryTask.ExecuteAsync(new ESRI.ArcGIS.Client.Tasks.Query()
            {

                OutFields = new ESRI.ArcGIS.Client.Tasks.OutFields() { "*" },
                Where = WhereStr
            });
        }



        #endregion

        #region 私有方法
        /// <summary>
        ///更新 FieldContentEnmu 字段的值
        /// </summary>
        /// <param name="e">参数</param>
        private void UpdateFieldContentEnmu(ESRI.ArcGIS.Client.Tasks.QueryEventArgs e)
        {
          
            //临时变量 
            List<string> strs = new List<string>();

            //得到字段内容
            var FieldContent = (from p in
                                    (from x in e.FeatureSet.Features select x.Attributes[WhereName].ToString())
                                select new
                                {
                                    a = 0,
                                    m = (new RetAction(() =>
                                    {

                                        if (!strs.Contains(p))
                                        {
                                            strs.Add(p);
                                        }
                                        return 0;
                                    }).Invoke())
                                }).ToList();


            FieldContentEnmu = strs;
        }
        #endregion



        #region INotifyPropertyChanged 成员

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 实现 属性改变的方法
        /// </summary>
        /// <param name="propertyName"></param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }


        #endregion

    }
}
namespace System.Linq
{
    using System.Collections.ObjectModel;
    /// <summary>
    /// 扩展方法
    /// </summary>
    public static class IEnumerableExtendMethod
    {
        /// <summary>
        /// 将集合转换成 ObservableCollection  对像
        /// </summary>
        /// <typeparam name="TSource">数据源</typeparam>
        /// <param name="source">数据</param>
        /// <returns></returns>
        public static ObservableCollection<TSource> ToObservableCollection<TSource>(this IEnumerable<TSource> source)
        {

            ObservableCollection<TSource> Result = new ObservableCollection<TSource>();

            foreach (TSource item in source.ToArray())
            {
                Result.Add(item);
            }

            return Result;
        }
    }
}
